package com.se.db;

import com.se.common.Group;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static com.se.common.Constant.GET_SQL_CONNECTION_FAILED;

public class DbGroup {
    private static volatile DbGroup instance;
    private static final Logger logger = LoggerFactory.getLogger(DbGroup.class);

    private DbGroup(){
    }

    public static DbGroup getInstance() {
        if(instance == null) {
            synchronized (DbGroup.class) {
                if(instance == null) {
                    instance = new DbGroup();
                }
            }
        }
        return instance;
    }

    public void add(Group group) throws SQLException {
        String sql = "INSERT INTO `group`(groupId,groupName,groupOwner,groupMembers,groupAI,notifyList) " +
                "VALUES (?,?,?,?,?,?)";
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, group.getGroupId());
            ps.setString(2, group.getGroupName());
            ps.setString(3, group.getGroupOwner());
            ps.setString(4, group.getGroupMembersAsString());
            ps.setString(5, group.getGroupAI());
            ps.setString(6, group.getNotifyListAsString());
            ps.executeUpdate();
        }

        logger.info("向数据库中添加新群组,群组ID为: {}", group.getGroupId());
        DbUtils.close(conn);
    }

    public Group get(int groupId) throws SQLException {
        String sql = "SELECT groupId,groupName,groupOwner,groupMembers,groupAI,notifyList" +
                " FROM `group` WHERE groupId=?";
        Group group = null;
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, groupId);
            try(ResultSet rs = ps.executeQuery()) {
                if(rs.next()) {
                    group = mapGroup(rs);
                }
            }
        }

        logger.info("向数据库中获取群组数据: {}", groupId);
        DbUtils.close(conn);
        return group;
    }

    public void update(Group group) throws SQLException {
        String sql = "UPDATE `group` SET groupName=?,groupMembers=?,groupAI=?,notifyList=?" +
                " WHERE groupId=?";
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, group.getGroupName());
            ps.setString(2, group.getGroupMembersAsString());
            ps.setString(3, group.getGroupAI());
            ps.setString(4, group.getNotifyListAsString());
            ps.setInt(5, group.getGroupId());
            ps.executeUpdate();
        }

        DbUtils.close(conn);
    }

    public void delete(int groupId) throws SQLException{
        String sql = "DELETE FROM `group` WHERE groupId=?";
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, groupId);
            ps.executeUpdate();
        }

        DbUtils.close(conn);
    }

    public int getNewGroupId() throws SQLException {
        String sql = "SELECT MAX(groupId) AS groupId FROM `group`";
        Connection conn = DbUtils.getConnection();
        int re;
        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ResultSet rs = ps.executeQuery();
            if(rs.next()) {
                re = rs.getInt("groupId") + 1;
            }
            else{
                re = 1000000;
            }
        }
        DbUtils.close(conn);
        return re;
    }

    public List<Group> search(String keyword) throws SQLException {
        String sql = "SELECT groupId,groupName,groupOwner,groupMembers,groupAI,notifyList" +
        " FROM `group` WHERE groupId like ? OR groupName like ?";
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }
        List<Group> re = new ArrayList<>();

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, '%' + keyword + '%');
            ps.setString(2, '%' + keyword + '%');
            ResultSet rs = ps.executeQuery();
            while(rs.next()) {
                re.add(mapGroup(rs));
            }
        }
        DbUtils.close(conn);
        return re;
    }

    public Group mapGroup(ResultSet rs) throws SQLException {
        Group group = new Group();
        group.setGroupId(rs.getInt("groupId"));
        group.setGroupName(rs.getString("groupName"));
        group.setGroupOwner(rs.getString("groupOwner"));
        group.setGroupMembersByString(rs.getString("groupMembers"));
        group.setGroupAI(rs.getString("groupAI"));
        group.setNotifyListByString(rs.getString("notifyList"));
        return group;
    }
}
